
package it.ibka;

import it.enrollement.System_Param;
import it.user.User;
import it.utils.Hash;
import java.util.Random;
import jpair.pairing.BigInt;
import jpair.pairing.Point;

/**
 * The IB_FG protocol is an elliptic curve version of the protocol of Fiore and Gennaro [FIORE2010IDENTITY]. This is an authenticated
protocol with its own native ID-based signatures, which does not rely on bilinear pairing computations.
 * 
 * [FIORE2010IDENTITY] Fiore, Dario and Gennaro, Rosario. Identity-based key exchange protocols without pairings. Springer. p. 42--77 2010
 *   
 * 
 * @author Francesco Rossi
 * @version 0.1
 * 
 */


public class IB_FG {

    // two User are needed for key establishment   
    int n = 2;
    System_Param parameter;
    Random rnd;
    User[] m;

    public IB_FG(User[] m, int n, System_Param param) {

        this.parameter = param;

        this.m = m;
        this.n = n;

    }

    public void Round1() {
        int i, is;


        for (i = 0; i < n; i++) {
            rnd = new Random();
            // choise t
            m[i].getIbka().setT(new BigInt(parameter.getE().getGroupOrder().bitLength(), rnd));
            // U = tP
            m[i].getIbka().setU(parameter.getE().getCurve().multiply(parameter.getP(), m[i].getIbka().getT()));

        }


        /*exchenge ID, Q and U*/
        for (i = 0; i < n; i++) {
            is = (i + 1) % n;
            m[i].getIbka().setIDe(m[is].getID());
            m[i].getIbka().setQe(m[is].getQ());
            m[i].getIbka().setUe(m[is].getIbka().getU());

        }



    }

    public void KeyDerivation() {
        int is, i;
        BigInt s1, h1;
        Point s2, s3, zs;
        Hash ut = new Hash();


        try {

            for (i = 0; i < n; i++) {
                /* (T + Ak)*/
                s1 = m[i].getIbka().getT().add(m[i].getKid());

                /* H1(IDe,Qe)*/
                h1 = ut.h1((m[i].getIbka().getIDe() + m[i].getIbka().getQe().toString()).getBytes("UTF-8"), parameter.getE().getCurve().getField());

                /* H1(IDe,Qe)Ppub */
                s2 = parameter.getE().getCurve().multiply(parameter.getPpub(), h1);

                /* Ue+Qe+H1(IDe,Qe)Ppub */
                s3 = parameter.getE().getCurve().add(s2, parameter.getE().getCurve().add(m[i].getIbka().getQe(), m[i].getIbka().getUe()));
                /* z1= (T + Ak)(Ue+Qe+H1(IDe,Qe)Ppub)*/
                m[i].getIbka().setZ1(parameter.getE().getCurve().multiply(s3, s1));
                /*z2= TUe */
                m[i].getIbka().setZ2(parameter.getE().getCurve().multiply(m[i].getIbka().getUe(), m[i].getIbka().getT()));

                zs = parameter.getE().getCurve().add(m[i].getIbka().getZ1(), m[i].getIbka().getZ2());

                //  z= H1(z1+z2)
                BigInt z = ut.h1(zs.toString().getBytes(), parameter.getE().getCurve().getField());


                m[i].getIbka().setZ(z);


                //     System.out.println("************ User "+i+" ***********");


                   System.out.println("Shared Key between A and B");

                   System.out.println(m[i].getIbka().getZ());
            }

        } catch (Exception c1) {
            c1.toString();

        }



    }
}
